extends CharacterBody2D

enum {MOVE, ATTACK}					# 模式

# 物理模拟
@export var speed = 100				# 最大速度
@export var friction = 1000			# 摩擦力1000
@export var acceleration = 1000		# 加速度

# 预加载
@onready var animationTree = $AnimationTree		# 动画树
@onready var audio = $"../FireMusic"			# 开火音效
@onready var playerBox = $".."					# 父容器

# 动画播放状态
@onready var animationState = animationTree.get("parameters/playback")
@onready var util = Util.new()

# 其他变量
var state = MOVE		# 当前状态
var isFire = false		# 是否开火
var direction = null	# 方向, 给其他类用的
var nodeName = 0

'''
	这个每帧自动调用一次
	@param delta 每帧之间的时间间隔
'''
func _physics_process(delta):
	match state:
		MOVE:
			move(delta)
		ATTACK:
			attack(delta)
			
'''
	生成子弹
	@param img 子弹贴图
	@param width 宽度
	@param heigth 高度
	@return 子弹
'''
func generateBullet(img, width, heigth):
	# 加载子弹场景
	var tempBullet = load("res://Weapon/Bullet.tscn").instantiate()
	
	# 寻找子弹贴图子节点
	var tempBulletSprite = util.findOne("$[Sprite2D]", tempBullet)
	# 为贴图节点设置图片, 大小
	tempBulletSprite.texture = load(img)
	tempBulletSprite.region_rect.size = Vector2(width, heigth)
	
	# 子弹碰撞箱
	var area2D = util.findOne("$[BulletArea2D]", tempBullet)
	# 子弹碰撞体
	var collisionShape = CollisionShape2D.new()
	# 碰撞体形状
	var rectangleShape = RectangleShape2D.new()
	# 碰撞体大小
	rectangleShape.size = Vector2(width / 1.5, heigth / 3.5)
	# 设置碰撞体形状
	collisionShape.shape = rectangleShape
	# 为碰撞箱加上碰撞体
	area2D.add_child(collisionShape)
	return tempBullet

func attack(delta):
	state = MOVE
	audio.play()
	var tempBullet = generateBullet("res://Weapon/Bullet.png", 50, 50)
	# 在玩家盒子中添加子弹子节点
	# 因为子弹是有多个的, 所以玩家点击一次攻击就会生成一个子弹
	playerBox.add_child(tempBullet)
	# 之后调用子弹的开火
	tempBullet.fire(direction, self, delta)
	
'''
	移动函数
	@param delta 每帧之间的时间间隔
'''
func move(delta):
	if Input.is_action_just_pressed("attack"):
		state = ATTACK
		
	'''
		Vector2(x, y)
		x = Input.get_axis("ui_left", "ui_right")	点left返回-1, 否则1
		y = Input.get_axis("ui_up", "ui_down")		点up返回-1, 否则1
	'''
	var vector2 = Vector2(Input.get_axis("ui_left", "ui_right"), Input.get_axis("ui_up", "ui_down"))
	# 用了勾股定理, 计算使对象斜向移动的距离
	vector2 = vector2.normalized()
	
	# 当向量不等于0时, 也就是角色在运动
	if vector2 != Vector2.ZERO:
		'''
			保存玩家的方向, 可以确认玩家点击的按键
			玩家推箱子时会使用到这个变量
			玩家开枪会用到
			
			以及后坐力也会用到
		'''
		direction = vector2
		'''
			加速度模拟
			以delta * acceleration的速度移动, 缓慢接近vector2 * speed速度
			- delta 每帧之间的时间间隔, 防止不同帧率位移距离不一样
			- velocity.x 	水平方向, -1左, 1右
			- acceleration 	加速度
			
			vector2 * speed 展开:
				Vector2(vector2.x * speed, vector2.y * speed)
		'''
		velocity = velocity.move_toward(direction * speed, delta * acceleration)
	else:
		'''
			摩擦力模拟
			否则向量为0, 代表角色停止运动了
			那么向量以delta * friction的速度靠近0向量
			- FRICTIO 摩擦力, 以这个摩擦系数缓慢靠近0速度
		'''
		velocity = velocity.move_toward(Vector2.ZERO, delta * friction)
	
	# 模拟碰撞的行走
	# 对象碰撞到刚体会被定在原地
	move_and_collide(velocity * delta)
	
	'''
		模拟滑动的行走
		对象碰到刚体, 会从上面滑落
		不用这个的原因是, 玩家推箱子会跟着箱子滑动
	'''
	# move_and_slide()

